#include "Acceptor.h"

void Acceptor::setAddrReuse() const
{
    int opt = 1;
    int ret = ::setsockopt(_socket.fd(), SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    ERR_CHECK(ret, -1, "setAddrReuse");
}

void Acceptor::setPortReuse() const
{
    int opt = 1;
    int ret = ::setsockopt(_socket.fd(), SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
    ERR_CHECK(ret, -1, "setAddrReuse");
}

void Acceptor::bind()
{
    sockaddr_in *addr = _local.getSockaddrPtr();
    int ret = ::bind(_socket.fd(), (sockaddr *)addr, sizeof(sockaddr_in));
    ERR_CHECK(ret, -1, "bind");
}

void Acceptor::listen() const
{
    int ret = ::listen(_socket.fd(), 128);
    ERR_CHECK(ret, -1, "listen");
}

Acceptor::Acceptor(const char *ip, unsigned short port)
    : _socket{}, _local{ip, port}
{
}

Acceptor::~Acceptor()
{
}

void Acceptor::ready()
{
    setAddrReuse();
    setPortReuse();
    bind();
    listen();
}

int Acceptor::accept()
{
    int cltFd = ::accept(_socket.fd(), nullptr, nullptr);
    ERR_CHECK(cltFd, -1, "accept");

    return cltFd;
}

int Acceptor::fd() const
{
    return _socket.fd();
}